package org.myhibernate.core.method;

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import org.myhibernate.cache.CacheContainer;
import org.myhibernate.cache.CacheContainers;
import org.myhibernate.cache.CacheItem;
import org.myhibernate.cache.SqlQueryMap;
import org.myhibernate.core.LanguageHandle;
import org.myhibernate.core.method.CacheQuery;
import org.myhibernate.core.method.GenericMethod;
import org.myhibernate.db.DataHelper;

public class PageSizeQuery<T> extends GenericMethod<T>
{
	private int count=0;
	private String sql="";
	private CacheQuery cacheQuery=null;
	private ArrayList<Object> currentIdList=null;
	@Override
	public void init(Class cls, Connection connection) 
	{
		super.init(cls, connection); 
		cacheQuery=new CacheQuery(connection, cls); 
	}
	@Override
	public void init(Class cl, DataHelper helper) {
		super.init(cl, helper);
		cacheQuery=new CacheQuery(cl, helper);
	}
	@Override
	public void init(Class cl, Connection connection, DataHelper helper) {
		super.init(cl, connection, helper);
		cacheQuery=new CacheQuery(cl, connection, helper);
	}
	public int query(String extSql) throws Exception
	{
		return query(extSql, null);
	}
	public int query(String extSql,String[] selectFields) throws Exception
	{
		if (getBuffer().length()>0) {
			getBuffer().delete(0, getBuffer().length());
		}
		String key=getCl().getName()+"_"+extSql;
		sql=extSql;
		count=0;
		CacheContainer cacheContainer=CacheContainers.getCache(ArrayList.class);
		if (cacheContainer.get(key)!=null)
		{
			currentIdList=(ArrayList<Object>) cacheContainer.get(key);
			count=currentIdList.size();
		}else 
		{
			try {
				currentIdList=queryIdList(extSql,selectFields);
				if (currentIdList != null)
				{
					count=currentIdList.size();
					cacheContainer.set(key,currentIdList);
					SqlQueryMap.set(getCl(), key);
				}
			} catch (Exception e) {
				count=0;
				e.printStackTrace();
				throw new RuntimeException(e.toString());
			}
			
		}
		return getCount();
	}
	public List<T> getListObject(int start,int end)
	{
		List<T> list=new ArrayList<T>();
		int iStart=0,iEnd=0;
		if (start<=count){iStart=start;}else {iStart=count;}
		if (end<=count){iEnd=end;} else{iEnd=count;}
		for (int k = iStart; k < iEnd; k++)
		{
			try {
				list.add((T) cacheQuery.getObject(currentIdList.get(k)));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return list;
	}
	public List<CacheItem> getListItem(int start,int end)
	{
		List<CacheItem> list=new ArrayList<CacheItem>();
		int iStart=0,iEnd=0;
		if (start<=count){iStart=start;}else {iStart=count;}
		if (end<=count){iEnd=end;} else{iEnd=count;}
		for (int k = iStart; k < iEnd; k++)
		{
			try {
				list.add(cacheQuery.getObjectItem(currentIdList.get(k)));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return list;
	}
	private ArrayList<Object> queryIdList(String extSql) throws Exception
	{
		return queryIdList(extSql, null);
	}
	private ArrayList<Object> queryIdList(String extSql,String[] selectFields) throws Exception
	{
		count=0;
		if (getBuffer().length()>0) {
			getBuffer().delete(0, getBuffer().length());
		}
		ArrayList<Object> idList=null;
		ResultSet resultSet=null;
		String id=getMapping().getId_Column();
		if (selectFields!=null)
		{
			for (int i = 0; i < selectFields.length; i++) 
			{
				id=id+","+selectFields[i];
			}
		}
		String table=getMapping().getTable();
		String columns=getMapping().getColumns();
		List<String> columnList=getMapping().getPropertyColList();
		LanguageHandle languageHandle=new LanguageHandle();
		getBuffer().append(" select "+id+" from "+table+" "+extSql);
		sql=getSql();
		try {
			resultSet=cacheQuery.executeQuerySql(sql);
			idList=new ArrayList<Object>();
			while(resultSet.next())
			{
				idList.add(resultSet.getObject(id));
			}
			count=idList.size();
		} catch (Exception e) 
		{
			e.printStackTrace();
			throw new RuntimeException(e.toString());
		}finally{
			if (resultSet!=null) {
				try {
					resultSet.close();
				} catch (Exception e2) {
				}
			}
		}
		return idList;
	}
	public boolean deletes(String extSql)throws Exception
	{
		String table=getMapping().getTable();
		String sql=" delete  from "+table+" "+extSql;
		try {
			cacheQuery.executeSql(sql);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e.toString());
		}
		//return false;
	}
	
	public int getCount() {
		return count;
	}
	public List<Object> getIdList() {
		return currentIdList;
	}
	public String getCurrentSql() {
		return this.sql;
	}
	public void close()
	{
		cacheQuery.close();
	}
	public CacheQuery getCacheQuery() {
		return cacheQuery;
	}
}
